package edu.gatech.cc.CFAWaffleFriesWheresMyStuff.common;

import java.util.List;

import edu.gatech.cc.CFAWaffleFriesWheresMyStuff.common.Datastore.ItemDoesNotExistException;
import edu.gatech.cc.CFAWaffleFriesWheresMyStuff.common.Item.Category;
import edu.gatech.cc.CFAWaffleFriesWheresMyStuff.common.Item.Type;

/**
 * Manages access to all items stored in the system.
 */
public class ItemManager {
	Datastore ds;
	
	/**
	 * Constructs a new ItemList instance setup to use the given datastore
	 * @param ds
	 */
	public ItemManager(Datastore ds){
		this.ds = ds;
	}
	
	/**
	 * Returns the specified item.
	 * @param ID the Item's unique id.
	 * @return The item requested.
	 * @throws ItemDoesNotExistException Thrown if there is no item with the given ID.
	 */
	public Item getItem(int ID) throws ItemDoesNotExistException{
		return ds.getItem(ID);
	}
	
	/**
	 * Creates a new item and saves it to the database.
	 * @param username Username of the User who created the item.
	 * @param name Name of the item.
	 * @param description Description of the Item.
	 * @param isOpen Whether or not the Item is open.
	 * @param category Category of the Item.
	 * @param type Type of the Item.
	 * @param location Location of the Item. 
	 * @param date Date of the Item.
	 * @param reward Reward of the Item.
	 */
	public void createItem(String username, String name, String description, boolean isOpen, Category category, Type type, String location, long date, double reward){
		Item newItem = new Item(ds.getNextItemID(), username, name, description, isOpen, category, type, location, date, reward);
		ds.saveItem(newItem);
	}
	
	/**
	 * Returns the user's list of items.
	 * @param username Username of the user to get items from.
	 * @return the user's list of items.
	 */
	public List<Item> getUserItems(String username){
		return ds.getUserItems(username);
	}
	
	/**
	 * Returns a list of items filtered by the given set of constraints.
	 * Non-null parameters will be searched for. A null parameter is a sort of wildcard that will not constrain the results.
	 * All parameters but date will only select exact matches.
	 * If a date is given, the method will return items posted on or since the date given.
	 * 
	 * @param type The type of item to search for
	 * @param openStatus The open/closed status to search for
	 * @param category The category of item to search for
	 * @param name The name to search for
	 * @param date The date to search for
	 * @param location The location to search for
	 * @param username The username to search for
	 * @return The list of resulting items which all comply with the given constraints
	 */
	public List<Item> getFilteredItems(String type, Boolean openStatus, String category, String name, Long date, String location, String username) {
		return ds.filterItems(type, openStatus, category, name, date, location, username);
	}
	
	/**
	 * Returns a list of Items that might be matches of the given Item.
	 * For example, when given a Photo Album lost in Atlanta, Ga, this method might return a Photo Album found in Atlanta, Ga.
	 * @param item The item to match
	 * @return A list of possible matches.
	 */
	public List<Item> getMatchesToItem(Item item) {
		String name = item.getName();
		String location = item.getLocation();
		Type type = item.getType();
		switch(type)
		{
		case Lost:
			type = Type.Found;
			break;
		case Found:
			type = Type.Lost;
			break;
		case Donation:
			type = Type.DonationRequest;
			break;
		case DonationRequest:
			type = Type.Donation;
			break;
		}
		return ds.filterItems(type.toString(), null, null, name, null, location, null);
	}
}
